package com.my.library.util;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Member;
import java.util.HashMap;
import java.util.Map;

import javax.annotation.PostConstruct;

import org.springframework.stereotype.Component;

import com.my.library.annotation.MyField;
import com.my.library.annotation.MyId;
import com.my.library.annotation.MyIgnoreField;
import com.my.library.annotation.MyTable;
import com.my.library.dao.impl.UserDAO;
import com.my.library.entity.Book;

@Component
public class EntityTableMapping {
	private String[] entities = {"com.my.library.entity.User", "com.my.library.entity.Application", "com.my.library.entity.Book"};
	private static final String  DEFAULT_ID_NAME = "id";
	private static Map<Member, String> tableFieldMapping = new HashMap<Member, String>();
	private static Map<Class, String> idMapping = new HashMap<Class, String>();
	
	@PostConstruct
	public void init() throws Exception {
		for(String entity: entities) {
			Class clazz = Class.forName(entity);
			//String entityName = clazz.getName();
			String simpleName = clazz.getSimpleName();
			MyTable mt = (MyTable) clazz.getAnnotation(MyTable.class);
			if(mt == null || mt.value().equals("")) {
				tableFieldMapping.put(clazz.getConstructor(), simpleName);
			} else {
				tableFieldMapping.put(clazz.getConstructor(), mt.value());
			}
			Field[] fs = clazz.getDeclaredFields();
			boolean hasId = false;
			for(Field f: fs) {
				if(f.getAnnotation(MyIgnoreField.class) != null) continue;
				//System.out.println("MyIgnoreField: " + f.getAnnotation(MyIgnoreField.class));
				MyField mi = f.getAnnotation(MyField.class);
				String fieldName = f.getName();
				//System.out.println("fieldName:" + fieldName);
				if(mi == null || mi.value().equals("")) {
					tableFieldMapping.put(f, fieldName);
				} else {
					tableFieldMapping.put(f, mi.value());
				}
				
				if(!hasId) {
					MyId id = f.getAnnotation(MyId.class);
					if(id != null) {
						hasId = true;
						idMapping.put(clazz, tableFieldMapping.get(f));
					}
				}
			}
			
			if(!hasId) {
				idMapping.put(clazz, DEFAULT_ID_NAME);
			}
		}
		System.out.println("mapping: " + tableFieldMapping);
	}
	
	public static void main(String[] args) throws Exception {
		new EntityTableMapping().init();
		System.out.println(EntityTableMapping.getTableOrFieldName(UserDAO.class.getConstructor()));
		
		System.out.println(UserDAO.class.getConstructor().getName());
	}
	
	public static String getTableOrFieldName(Member entity) {
		return tableFieldMapping.get(entity) == null ? (entity instanceof Constructor ? entity.getDeclaringClass().getSimpleName() : entity.getName()) : tableFieldMapping.get(entity);
	}
	
	public static String getTableId(Class<?> entity) {
		return idMapping.get(entity) == null ? DEFAULT_ID_NAME : idMapping.get(entity); 
	}
}
